import { computed, ComputedRef, reactive, ref, watchEffect } from 'vue'
import { defineStore } from 'pinia'

export const useSgesMAStore = defineStore('sgesCalMA', () => {

  const capChargeTotalSta = ref<number>(10) // 总充电容量
  const powerChargeTotalSta = ref<number>(2) // 总充电功率
  const totalChargeTime = ref<number>(2) // 额定充电时间
  const cal_power = ref<boolean>(false) // 计算模式：是否根据容量和时间计算功率

  const heightMT = ref(100) // 山体高度，可以有效利用的高度
  const slopeDegree = ref(20) // 山坡角度，角度值，不是弧度
  const slopeDegreeRad = computed(() => slopeDegree.value * Math.PI / 180)
  const numRails = ref(2)
  const slopeDistance = computed(() => {
    return heightMT.value / Math.tan(slopeDegreeRad.value)
  })
  const lengthSlope = computed(() => heightMT.value / Math.sin(slopeDegreeRad.value))

  const gapBlocks = ref(5)
  const vibrant_para = ref<number>(1)

  const vibrant_option = [
    {
      label: '重物块数量',
      value: 1
    }, {
      label: '重物块密度',
      value: 2
    }, {
      label: '重物块长',
      value: 3
    }, {
      label: '重物块宽',
      value: 4
    }, {
      label: '重物块高',
      value: 5
    }, {
      label: '系统效率',
      value: 6
    }
  ]

  watchEffect(() => {
    if (cal_power.value) {
      powerChargeTotalSta.value = computed(() => capChargeTotalSta.value / totalChargeTime.value).value
    } else {
      totalChargeTime.value = computed(() => capChargeTotalSta.value / powerChargeTotalSta.value).value
    }
  })

  const density = ref(2400)  // 2
  const lengthBlock = ref(3) // 3
  const widthBlock = ref(3) // 4
  const heightBlock = ref(3) // 5
  const etaSystem = ref(0.75)
  const volumeBlock = ref(0)
  const massBlock = ref(0)
  const etaCharge = ref(1)
  const etaDischarge = ref(1)
  const widthSlope = ref(20)

  const totalBlocksNum = ref(0)

  const totalMassBlocks = ref(0)
  const totalGravityEnergy = ref(0)
  const g = ref(9.8)
  watchEffect(() => {
    switch (vibrant_para.value) {
      case 1: // 计算重物块数量
        volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
        etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
        etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
        totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
        totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightMT.value / g.value).value
        volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
        massBlock.value = computed(() => volumeBlock.value * density.value).value
        totalBlocksNum.value = computed(() => totalMassBlocks.value / massBlock.value).value
        break
      case 2: // 计算重物块密度
        volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
        etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
        etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
        totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
        totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightMT.value / g.value).value
        massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
        density.value = computed(() => massBlock.value / volumeBlock.value).value
        break
      case 3:
        etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
        etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
        totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
        totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightMT.value / g.value).value
        massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
        volumeBlock.value = computed(() => massBlock.value / density.value).value
        lengthBlock.value = computed(() => volumeBlock.value / widthBlock.value / heightBlock.value).value
        break
      case 4:
        etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
        etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
        totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
        totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightMT.value / g.value).value
        massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
        volumeBlock.value = computed(() => massBlock.value / density.value).value
        widthBlock.value = computed(() => volumeBlock.value / lengthBlock.value / heightBlock.value).value
        break
      case 5:
        etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
        etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
        totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
        totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightMT.value / g.value).value
        massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
        volumeBlock.value = computed(() => massBlock.value / density.value).value
        heightBlock.value = computed(() => volumeBlock.value / lengthBlock.value / widthBlock.value).value
        break
      case 6: // eta
        volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
        massBlock.value = computed(() => volumeBlock.value * density.value).value
        totalMassBlocks.value = computed(() => massBlock.value * totalBlocksNum.value).value
        totalGravityEnergy.value = computed(() => totalMassBlocks.value * g.value * heightMT.value).value
        etaCharge.value = computed(() => totalGravityEnergy.value / capChargeTotalSta.value / 3600000000).value
        etaDischarge.value = computed(() => etaCharge.value).value
        etaSystem.value = computed(() => etaCharge.value * etaDischarge.value).value
        break
      default:
        volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
        massBlock.value = computed(() => volumeBlock.value * density.value).value
        break

    }
  })

  const totalGravityEnergy_MJ = computed(() => totalGravityEnergy.value / 1000000) // 重物的总重力势能
  const capDischargeTotalSta = computed(() => capChargeTotalSta.value * etaSystem.value)  // 电站总发电容量
  const weightBlock = computed(() => massBlock.value * g.value)  // 重物块的重力
  const etaCharge_100 = computed(() => etaCharge.value * 100)  // 系统充电效率，单位%
  const etaDischarge_100 = computed(() => etaDischarge.value * 100)  // 系统发电效率，单位%
  const etaSystem_100 = computed(() => etaSystem.value * 100)  // 系统效率，单位%

  const areaControlRoom = ref(50)  // 集控室占地面积

  // 单个重物重力在运行方向的分量
  const forceWeightLocalX = computed(() => weightBlock.value * Math.sin(slopeDegreeRad.value))

  const numBlocksOnSingleRail = computed(() => lengthSlope.value / (gapBlocks.value + lengthBlock.value)) // 单条轨道上运行时，单个轨道上运行的重物块numBlocksWhenRunning
  const integerNumBlocksOnSingleRail = computed(() => Math.floor(numBlocksOnSingleRail.value)) // 单条轨道上运行时，单个轨道上运行的重物块numBlocksWhenRunning
  const powerMechanic = computed(() => powerChargeTotalSta.value * 1000000 * etaCharge.value)
  const velBlock = computed(() => powerMechanic.value / forceWeightLocalX.value / numBlocksOnSingleRail.value / numRails.value)
  const timeSingleBlock = computed(() => lengthSlope.value / velBlock.value)
  const timeIntervalOfBlocks = computed(() => (gapBlocks.value + lengthBlock.value) / velBlock.value)

  const totalRunningTime = computed(() => totalBlocksNum.value / numRails.value * timeIntervalOfBlocks.value / 3600)
  const totalRunningTimeAct = computed(() => totalRunningTime.value + timeSingleBlock.value / 3600 + lengthBlock.value / velBlock.value / 3600)
  const timeAccerlate = ref(10) // 加速时间

  // 新增加速度计算
  const acceleration = computed(() => velBlock.value / timeAccerlate.value)
  const frictionFactor = ref(0.005) // 摩擦系数
  const frictionForce = computed(() => massBlock.value * g.value * frictionFactor.value)
  const forceDrive = computed(() => acceleration.value * massBlock.value + frictionForce.value) // 驱动力
  const powerDrive = computed(() => forceDrive.value * velBlock.value)
  // 驱动力功率的裕度
  const powerDriveMargin = ref(2) // 驱动力功率的裕度
  const powerDriveDesign = computed(() => powerDriveMargin.value * powerDrive.value) // 驱动力功率的裕度

  const lengthAccelerate = ref(8) // 预留的加速段长度，即储存区中最靠近提升系统的重物与提升系统之间的间距
  const lengthStorage = computed(() => totalBlocksNum.value / numRails.value * lengthBlock.value)
  const lengthMerge = ref(5) // 即提升系统水平段的延伸长度
  const gap_rails = ref(1.435) // 中国标准铁轨的间距是1.435米
  const height_sleeper = ref(0.05)
  const width_sleeper = ref(0.1)
  const radius_wheel = ref(0.2) // 重物小车轮子直径
  const thick_wheel = ref(0.04) // 重物小车轮子厚度

  const calInfo = computed(() => {
  })

  const displayInfo = ref<{
    name?: string,
    subdomain?:
      {
        title: string,
        [key: string]: string | number | undefined | {
          value: string | number,
          editable: boolean,
          ref: string
        } | any[]
      }[]
  }>({})
  return {
    displayInfo,
    radius_wheel, thick_wheel,
    height_sleeper,
    width_sleeper,
    gap_rails,
    lengthMerge,
    lengthAccelerate,
    lengthStorage,
    powerDriveDesign,
    powerDriveMargin,
    powerDrive,
    timeAccerlate,
    forceDrive,
    frictionForce: frictionForce,
    frictionFactor,
    acceleration, // 添加到返回对象
    totalRunningTimeAct,
    totalRunningTime,
    timeSingleBlock,
    timeIntervalOfBlocks,
    powerMechanic,
    calInfo,
    heightMT,
    slopeDegree,
    slopeDistance,
    forceWeightLocalX,
    areaControlRoom,
    velBlock,
    etaCharge_100,
    etaDischarge_100,
    etaSystem_100,
    capChargeTotalSta,
    capDischargeTotalSta,
    powerChargeTotalSta,
    totalChargeTime,
    cal_power,
    vibrant_para,
    vibrant_option,
    density,
    lengthBlock,
    widthBlock,
    heightBlock,
    etaSystem,
    volumeBlock,
    massBlock,
    etaCharge,
    etaDischarge,
    totalBlocksNum,
    totalMassBlocks,
    totalGravityEnergy,
    g,
    totalGravityEnergy_MJ,
    weightBlock,
    numRails,
    gapBlocks,
    slopeDegreeRad,
    lengthSlope,
    numBlocksOnSingleRail,
    integerNumBlocksOnSingleRail,
    widthSlope
  }
})

